﻿using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Idlesoft.Utils
{
	public static class DirectoryExtensions
	{
		#region exists
		public static bool DirectoryExists(this string path)
		{
			return Directory.Exists(path);
		}
		#endregion exists

		#region create
		public static void CreateDirectory(string path)
		{
			Directory.CreateDirectory(path);
		}
		#endregion create

		#region find
		public static string[] FindDirectories(this string path, string pattern, bool recursive = false)
		{
			return Directory.GetDirectories(path, pattern, recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly);
		}
		public static string[] FindDirectories(this string path, Func<string, bool> selector = null)
		{
			string[] directories = Directory.GetDirectories(path);
			return selector != null ? directories.Where(selector).ToArray() : directories;
		}
		#endregion find

		#region copy
		public static bool CopyDirectory(this string src, string dst, bool recursive = false)
		{
			Directory.CreateDirectory(dst);
			FileExtensions.CopyFiles(src, dst);
			if (recursive)
				CopyDirectories(src, dst, "*", recursive);
			return Directory.Exists(dst);
		}
		public static int CopyDirectories(this string src, string dst, string pattern, bool recursive = false)
		{
			return FindDirectories(src, pattern, recursive).Select(dir => CopyDirectory(dir, Path.Combine(dst, Path.GetFileName(dir)), recursive)).Count(b => b);
		}
		public static int CopyDirectories(this string src, string dst, Func<string, bool> selector = null)
		{
			return FindDirectories(src, selector).Select(dir => CopyDirectory(dir, Path.Combine(dst, Path.GetFileName(dir)))).Count(b => b);
		}
		#endregion copy

		#region move
		public static bool MoveDirectory(this string src, string dst, bool recursive = false)
		{
			Directory.Move(src, dst);
			FileExtensions.MoveFiles(src, dst);
			if (recursive)
				MoveDirectories(src, dst, "*", recursive);
			return Directory.Exists(dst);
		}
		public static int MoveDirectories(this string src, string dst, string pattern, bool recursive = false)
		{
			return FindDirectories(src, pattern, recursive).Select(dir => MoveDirectory(dir, Path.Combine(dst, Path.GetFileName(dir)))).Count(b => b);
		}
		public static int MoveDirectories(this string src, string dst, Func<string, bool> selector = null)
		{
			return FindDirectories(src, selector).Select(dir => MoveDirectory(dir, Path.Combine(dst, Path.GetFileName(dir)))).Count(b => b);
		}
		#endregion move

		#region delete
		public static bool DeleteDirectory(this string path, bool recursive = false)
		{
			FileExtensions.DeleteFiles(path, "*", recursive);
			Directory.Delete(path, recursive);
			return !Directory.Exists(path);
		}
		public static int DeleteDirectories(this string src, string dst, string pattern, bool recursive = false)
		{
			return FindDirectories(src, pattern, recursive).Select(dir => DeleteDirectory(dir)).Count(b => b);
		}
		public static int DeleteDirectories(this string src, string dst, Func<string, bool> selector = null)
		{
			return FindDirectories(src, selector).Select(dir => DeleteDirectory(dir)).Count(b => b);
		}
		#endregion delete

		#region stuff
		public static string Parent(this string directory, int number = 1)
		{
			for (int i = 0; i < number; ++i)
			{
				if (Directory.Exists(directory))
					directory = Directory.GetParent(directory).FullName;
				else throw new DirectoryNotFoundException("directory:" + directory);
			}

			return directory;
		}
		#endregion stuff
	}
}
